﻿"""Lead management endpoints."""

from __future__ import annotations

from datetime import datetime
from typing import Any

from uuid import UUID, uuid4

from fastapi import APIRouter, Body, Depends, HTTPException, Query, Response, status
from sqlalchemy.orm import Session
from pydantic import BaseModel, Field

from ...deps import (
    get_ai_summary_service,
    get_ai_extraction_service,
    get_current_user,
    get_lead_service,
    get_property_match_service,
    get_db,
)
from ....models.enums import LeadStage
from ....models.user import User
from ....repositories.lead_repository import LeadRepository
from ....schemas.lead import LeadCreate, LeadListOut, LeadOut, LeadUpdate
from ....schemas.lead_ai_summary import LeadAISummaryCreate, LeadAISummaryOut, LeadAISummaryUpdate
from ....schemas.lead_contact import LeadContactCreate, LeadContactOut, LeadContactUpdate
from ....schemas.lead_note import LeadNoteCreate, LeadNoteOut, LeadNoteUpdate
from ....schemas.property_match import PropertyMatchListResponse
from ....schemas.common import BulkDeleteRequest, BulkOperationResponse
from ....services.ai_summary_service import AISummaryService
from ....services.lead_service import LeadService
from ....services.property_match_service import PropertyMatchService

router = APIRouter(tags=["leads"])


# 为leads创建专用别名，保持API兼容性
class LeadBulkDeleteRequest(BulkDeleteRequest):
    """批量删除客户请求."""

    pass


@router.get("/", response_model=LeadListOut)
def list_leads(
    owner_id: int | None = Query(default=None, description="Filter by owner id"),
    stage: LeadStage | None = Query(default=None, description="Filter by lead stage"),
    name: str | None = Query(default=None, description="Filter by name (fuzzy search)"),
    phone: str | None = Query(default=None, description="Filter by phone (fuzzy search)"),
    page: int = Query(default=1, ge=1, description="Page number"),
    page_size: int = Query(default=50, ge=1, le=200, description="Items per page"),
    lead_service: LeadService = Depends(get_lead_service),
    current_user: User = Depends(get_current_user),
) -> LeadListOut:
    # Calculate skip offset from page number
    skip = (page - 1) * page_size

    # 优化：使用单次查询同时获取数据和总数（减少50%数据库查询）
    leads, total = lead_service.lead_repo.filter_by_criteria_with_total(
        stage=stage,
        owner_id=owner_id or current_user.id,
        name=name,
        phone=phone,
        skip=skip,
        limit=page_size
    )

    # Build response
    items = [LeadOut.model_validate(lead) for lead in leads]
    return LeadListOut(total=total, items=items, page=page, page_size=page_size)


@router.post("/", response_model=LeadOut, status_code=status.HTTP_201_CREATED)
def create_lead(
    payload: LeadCreate,
    lead_service: LeadService = Depends(get_lead_service),
    session: Session = Depends(get_db),
    current_user: User = Depends(get_current_user),
) -> LeadOut:
    import_batch_id = payload.import_batch_id or uuid4()
    lead_payload = payload.model_copy(
        update={"owner_id": current_user.id, "import_batch_id": import_batch_id}
    )
    lead = lead_service.create_lead(lead_payload)
    session.commit()
    return LeadOut.model_validate(lead)


@router.get("/{lead_id}", response_model=LeadOut)
def get_lead(
    lead_id: int,
    lead_service: LeadService = Depends(get_lead_service),
) -> LeadOut:
    lead = lead_service.get_lead(lead_id)
    if lead is None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Lead not found")
    return LeadOut.model_validate(lead)


@router.put("/{lead_id}", response_model=LeadOut)
def update_lead(
    lead_id: int,
    payload: LeadUpdate,
    lead_service: LeadService = Depends(get_lead_service),
    session: Session = Depends(get_db),
) -> LeadOut:
    updated = lead_service.update_lead(lead_id, payload)
    if updated is None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Lead not found")
    session.commit()
    return LeadOut.model_validate(updated)


@router.delete("/{lead_id}", status_code=status.HTTP_204_NO_CONTENT)
def delete_lead(
    lead_id: int,
    session: Session = Depends(get_db),
    current_user: User = Depends(get_current_user),
) -> Response:
    """软删除客户记录（可恢复）."""
    repo = LeadRepository(session)
    deleted = repo.soft_delete(lead_id, current_user.id)
    if not deleted:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Lead not found")
    session.commit()
    # 204状态码不需要返回内容
    return Response(status_code=status.HTTP_204_NO_CONTENT)


@router.post("/{lead_id}/restore", response_model=LeadOut)
def restore_lead(
    lead_id: int,
    session: Session = Depends(get_db),
    current_user: User = Depends(get_current_user),
) -> LeadOut:
    """恢复软删除的客户记录."""
    repo = LeadRepository(session)
    restored = repo.restore(lead_id)
    if not restored:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND, detail="Lead not found or not deleted"
        )
    session.commit()

    # Fetch and return restored lead
    lead = repo.get(lead_id)
    if not lead:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Lead not found")
    return LeadOut.model_validate(lead)


@router.get("/deleted/list", response_model=LeadListOut)
def list_deleted_leads(
    owner_id: int | None = Query(default=None, description="Filter by owner id"),
    page: int = Query(default=1, ge=1, description="Page number"),
    page_size: int = Query(default=50, ge=1, le=200, description="Items per page"),
    lead_service: LeadService = Depends(get_lead_service),
    current_user: User = Depends(get_current_user),
) -> LeadListOut:
    """获取已软删除的客户列表."""
    skip = (page - 1) * page_size

    # Get deleted leads
    deleted_leads = lead_service.lead_repo.get_deleted_leads(
        owner_id=owner_id or current_user.id, skip=skip, limit=page_size
    )

    # Count total deleted leads
    total = len(
        lead_service.lead_repo.get_deleted_leads(
            owner_id=owner_id or current_user.id,
            skip=0,
            limit=10000,  # Get all for count (TODO: optimize with count query)
        )
    )

    items = [LeadOut.model_validate(lead) for lead in deleted_leads]
    return LeadListOut(total=total, items=items, page=page, page_size=page_size)


@router.post("/bulk-delete", response_model=BulkOperationResponse)
def bulk_delete_leads(
    payload: BulkDeleteRequest,
    session: Session = Depends(get_db),
    current_user: User = Depends(get_current_user),
) -> BulkOperationResponse:
    """批量软删除客户记录（最多50个）.

    请求体示例:
    ```json
    {
        "lead_ids": [1, 2, 3, 4, 5]
    }
    ```

    返回示例:
    ```json
    {
        "success": 4,
        "failed": 0,
        "not_found": 1,
        "message": "批量删除完成：成功4条，未找到1条"
    }
    ```
    """
    repo = LeadRepository(session)
    # Convert str IDs to int IDs
    lead_ids = [int(id) for id in (payload.lead_ids or [])]
    result = repo.bulk_soft_delete(lead_ids, current_user.id)
    session.commit()

    message = f"批量删除完成：成功{result['success']}条"
    if result["not_found"] > 0:
        message += f"，未找到{result['not_found']}条"

    return BulkOperationResponse(
        success=bool(result["success"]),
        message=message,
        processed_count=result["success"] + result["failed"] + result["not_found"],
        failed_count=result["failed"],
        failed=result["failed"],
        not_found=result["not_found"],
    )


@router.post("/bulk-restore", response_model=BulkOperationResponse)
def bulk_restore_leads(
    payload: BulkDeleteRequest,  # 复用相同的Schema
    session: Session = Depends(get_db),
    current_user: User = Depends(get_current_user),
) -> BulkOperationResponse:
    """批量恢复已删除的客户记录（最多50个）.

    请求体示例:
    ```json
    {
        "lead_ids": [1, 2, 3]
    }
    ```

    返回示例:
    ```json
    {
        "success": 3,
        "failed": 0,
        "not_found": 0,
        "message": "批量恢复完成：成功3条"
    }
    ```
    """
    repo = LeadRepository(session)
    # Convert str IDs to int IDs
    lead_ids = [int(id) for id in (payload.lead_ids or [])]
    result = repo.bulk_restore(lead_ids)
    session.commit()

    message = f"批量恢复完成：成功{result['success']}条"
    if result["not_found"] > 0:
        message += f"，未找到或未删除{result['not_found']}条"

    return BulkOperationResponse(
        success=bool(result["success"]),
        message=message,
        processed_count=result["success"] + result["failed"] + result["not_found"],
        failed_count=result["failed"],
        failed=result["failed"],
        not_found=result["not_found"],
    )


@router.post(
    "/{lead_id}/contacts", response_model=LeadContactOut, status_code=status.HTTP_201_CREATED
)
def add_contact(
    lead_id: int,
    payload: LeadContactCreate,
    lead_service: LeadService = Depends(get_lead_service),
    session: Session = Depends(get_db),
) -> LeadContactOut:
    data = payload.model_copy(update={"lead_id": lead_id})
    contact = lead_service.add_contact(data)
    session.commit()
    return LeadContactOut.model_validate(contact)


@router.put("/contacts/{contact_id}", response_model=LeadContactOut)
def update_contact(
    contact_id: int,
    payload: LeadContactUpdate,
    lead_service: LeadService = Depends(get_lead_service),
    session: Session = Depends(get_db),
) -> LeadContactOut:
    contact = lead_service.update_contact(contact_id, payload)
    if contact is None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Contact not found")
    session.commit()
    return LeadContactOut.model_validate(contact)


@router.post("/{lead_id}/notes", response_model=LeadNoteOut, status_code=status.HTTP_201_CREATED)
def add_note(
    lead_id: int,
    payload: LeadNoteCreate,
    lead_service: LeadService = Depends(get_lead_service),
    current_user: User = Depends(get_current_user),
    session: Session = Depends(get_db),
) -> LeadNoteOut:
    data = payload.model_copy(update={"lead_id": lead_id, "author_id": current_user.id})
    note = lead_service.add_note(data)
    session.commit()
    return LeadNoteOut.model_validate(note)


@router.put("/notes/{note_id}", response_model=LeadNoteOut)
def update_note(
    note_id: int,
    payload: LeadNoteUpdate,
    lead_service: LeadService = Depends(get_lead_service),
    session: Session = Depends(get_db),
) -> LeadNoteOut:
    note = lead_service.update_note(note_id, payload)
    if note is None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Note not found")
    session.commit()
    return LeadNoteOut.model_validate(note)


@router.post(
    "/{lead_id}/ai-summary", response_model=LeadAISummaryOut, status_code=status.HTTP_201_CREATED
)
def trigger_ai_summary(
    lead_id: int,
    payload: LeadAISummaryCreate,
    ai_service: AISummaryService = Depends(get_ai_summary_service),
    session: Session = Depends(get_db),
) -> LeadAISummaryOut:
    data = payload.model_copy(update={"lead_id": lead_id})
    summary = ai_service.create_summary(data)
    session.commit()
    return LeadAISummaryOut.model_validate(summary)


@router.get("/{lead_id}/ai-summary", response_model=list[LeadAISummaryOut])
def list_ai_summaries(
    lead_id: int,
    ai_service: AISummaryService = Depends(get_ai_summary_service),
) -> list[LeadAISummaryOut]:
    repo = ai_service.ai_repo
    summaries = repo.get_by_lead(lead_id)
    return [LeadAISummaryOut.model_validate(item) for item in summaries]


@router.post("/ai-summary/{summary_id}/review", response_model=LeadAISummaryOut)
def review_ai_summary(
    summary_id: int,
    ai_service: AISummaryService = Depends(get_ai_summary_service),
    current_user: User = Depends(get_current_user),
    session: Session = Depends(get_db),
) -> LeadAISummaryOut:
    reviewed = ai_service.mark_reviewed(summary_id, current_user.id)
    if reviewed is None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="AI summary not found")
    session.commit()
    return LeadAISummaryOut.model_validate(reviewed)


@router.patch("/ai-summary/{summary_id}", response_model=LeadAISummaryOut)
def update_ai_summary(
    summary_id: int,
    payload: LeadAISummaryUpdate,
    ai_service: AISummaryService = Depends(get_ai_summary_service),
    session: Session = Depends(get_db),
) -> LeadAISummaryOut:
    summary = ai_service.ai_repo.get(summary_id)
    if summary is None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="AI summary not found")
    updated = ai_service.ai_repo.update(summary, payload)
    session.commit()
    return LeadAISummaryOut.model_validate(updated)


@router.get("/{lead_id}/match-properties", response_model=PropertyMatchListResponse)
def match_properties(
    lead_id: int,
    top_n: int = Query(default=10, ge=1, le=50, description="返回前N个匹配结果"),
    min_score: float = Query(default=50.0, ge=0, le=100, description="最低匹配分数阈值"),
    include_unavailable: bool = Query(default=False, description="是否包含已租出房源"),
    match_service: PropertyMatchService = Depends(get_property_match_service),
) -> PropertyMatchListResponse:
    """
    智能匹配房源 (AI增强).

    使用AI语义分析提取客户需求,结合规则引擎进行多维度评分,
    返回按匹配度降序排列的房源列表.

    Args:
        lead_id: 客户ID
        top_n: 返回前N个匹配结果 (默认10, 最大50)
        min_score: 最低匹配分数阈值 (0-100, 默认50)
        include_unavailable: 是否包含已租出房源 (默认False)

    Returns:
        PropertyMatchListResponse: 匹配结果列表,包含:
        - total_matched: 匹配房源总数
        - matches: 匹配结果列表 (包含分数明细、匹配理由、AI洞察)

    Raises:
        404: 客户不存在
    """
    return match_service.match_properties(
        lead_id=lead_id,
        top_n=top_n,
        min_score=min_score,
        include_unavailable=include_unavailable,
    )


@router.post("/extract-from-notes")
def extract_from_notes(
    notes: str = Body(..., description="备注文本"),
    existing_data: dict | None = Body(None, description="已有字段数据"),
    ai_service = Depends(get_ai_extraction_service),
) -> dict:
    """
    从备注中提取关键信息（轻量级）

    用于传统表单的智能补全功能。
    从用户输入的备注中自动识别：预算范围、需求类型、户型、区域偏好等。

    Args:
        notes: 备注文本内容
        existing_data: 已有的表单数据（避免覆盖用户手动输入）

    Returns:
        {
            "budget_range": "7000-8000",
            "demand_type": "rent_whole",
            "layout": "2室1厅",
            "area_preferences": ["朝阳区", "望京"]
        }

    Examples:
        输入备注：
        "客户想在朝阳区找两居室，预算 7000-8000，希望靠近地铁"

        返回结果：
        {
            "budget_range": "7000-8000",
            "demand_type": "rent_whole",
            "layout": "2室1厅",
            "area_preferences": ["朝阳区"]
        }
    """
    # 调用 AI 提取服务的轻量级方法
    extracted = ai_service.extract_from_notes_light(notes, existing_data)

    return {
        "success": True,
        "data": extracted,
        "message": f"已提取 {len(extracted)} 个字段" if extracted else "未提取到有效信息"
    }
